/**
 * 
 */
package com.whf15.o2o.dao.split;

import java.util.Locale;
import java.util.Properties;
import java.util.concurrent.Executor;

import org.apache.ibatis.cache.TransactionalCacheManager;
import org.apache.ibatis.executor.keygen.SelectKeyGenerator;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.SqlCommandType;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Plugin;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.transaction.support.TransactionSynchronizationManager;

/** 
* @author 作者 :whfo 
* @version 创建时间：2021年5月21日 下午8:05:56 
* 类说明 
*/
public class DynamicDataSourceInterceptor implements Interceptor{
	private static Logger logger =  LoggerFactory.getLogger(DynamicDataSourceInterceptor.class);

	private static final String REGEX = ".*insert\\u0020.*|.*delete\\u0020.*|.*update\\u0020.*";
	@Override
	public Object intercept(Invocation invocation) throws Throwable {
		// 主要的拦截方法
		boolean synchronizationActive = TransactionSynchronizationManager.isActualTransactionActive();
		Object[] objects = invocation.getArgs();
		MappedStatement ms = (MappedStatement) objects[0];
		String lookupKey = DynamicDataSourceHolder.DB_MASTER;
		if(synchronizationActive != true) {
			//读方法
			if(ms.getSqlCommandType().equals(SqlCommandType.SELECT)) {
				//selectKey 为自增id查询主键（SELECT LAST_INSERT_ID()）方法，使用主库
				if(ms.getId().contains(SelectKeyGenerator.SELECT_KEY_SUFFIX)) {
					lookupKey = DynamicDataSourceHolder.DB_MASTER;
				}else {
					BoundSql boundSql = ms.getSqlSource().getBoundSql(objects[1]);
					String sql = boundSql.getSql().toLowerCase(Locale.CHINA).replaceAll("[\\t\\n\\r]"," ");
					if(sql.matches(REGEX)) {
						lookupKey = DynamicDataSourceHolder.DB_MASTER;
					}else {
						lookupKey = DynamicDataSourceHolder.DB_SLAVE;
					}
				}
			}
		}else {
			lookupKey = DynamicDataSourceHolder.DB_MASTER;
		}
		logger.debug("设置方法[{}]use[{}]Strategy,SqlCommonType[{}]",ms.getId(),lookupKey,ms.getSqlCommandType().name());
		DynamicDataSourceHolder.setDbType(lookupKey);
		return invocation.proceed();
	}

	
	@Override
	public Object plugin(Object target) {
		// 返回封装好的对象，代理对象
		
		if(target instanceof Executor) {
			return Plugin.wrap(target, this);
		}else {
			return target;	
		}		
	}


	@Override
	public void setProperties(Properties arg0) {
		//类初始化的时候设置
		
	}
	//使用路由
}
